using System;
using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ScrollContainer : BaseUI,IBeginDragHandler, IDragHandler, IEndDragHandler
{
    public RectTransform content;
    public GameObject itemPrefab;
    public RectTransform[] templates;
    private float spacing = 120;
    private int onePageItemCount = 5;
    public float animDuration = 0.5f;

    public Button btn_Last, btn_Next;

    public List<string> dataList = new List<string>()
    {
        "数据1",
        "数据2",
        "数据3",
        "数据4",
        "数据5",
        "数据6",
        "数据7",
        "数据8",
        "数据9",
        "数据10",
        "数据11",
        "数据12",
        "数据13",
        "数据14",
        "数据15",
        "数据16",
    };

    public int curIndex = 0;
    
    // 鼠标拖拽相关变量
    public bool isVerticalScroll = false; // false为水平滚动，true为垂直滚动
    private Vector2 dragStartPos;
    private bool isDragging = false;
    private float dragThreshold = 50f; // 触发切换的最小拖拽距离
    
    private void Awake()
    {
        onePageItemCount = templates.Length - 2;
    
        // 根据滚动方向计算spacing
        if (isVerticalScroll)
        {
            spacing = Mathf.Abs(templates[1].position.y - templates[0].position.y);
        }
        else
        {
            spacing = Mathf.Abs(templates[1].position.x - templates[0].position.x);
        }
    }

    private void Start()
    {
        Init();
        btn_Last.onClick.AddListener(() => LastIndex());
        btn_Next.onClick.AddListener(() => NextIndex());
    }

    public List<GameObject> itemList = new List<GameObject>();
    
    public void Init()
    {
        for (int i = 0; i < templates.Length; i++)
        {
            GameObject go = Instantiate(itemPrefab, content);
            Vector3 targetPos = Vector3.zero;
            Vector3 targetRot = Vector3.zero;
            targetPos = templates[i].position;
            targetRot = templates[i].eulerAngles;

            go.GetComponent<RectTransform>().position = targetPos;
            go.GetComponent<RectTransform>().eulerAngles = targetRot;
            go.GetComponent<RectTransform>().sizeDelta= templates[0].sizeDelta;

            int realIndex = GetRealIndex(curIndex - onePageItemCount / 2 + i - 1);
            go.GetComponentInChildren<Text>().text = GetData(realIndex);
            Button btn = go.GetComponent<Button>();
            btn.onClick.RemoveAllListeners();
            int index = i;
            int[] map = new[] { -3, -2, -1, 0, 1, 2, 3 };
            btn.onClick.AddListener(() =>
            {
                Debug.Log("切换至" + index);
                StartCoroutine(QuickChange(map[index]));
            });

            itemList.Add(go);
        }
        int middleIndex = templates.Length / 2;
        itemList[middleIndex].transform.localScale = Vector3.one * 1.5f;
        itemList[middleIndex].GetComponent<Graphic>().color = Color.yellow;
    }

    public bool isTurning = false;
    
    public void NextIndex(float duration = -1)
    {
        if (isTurning) return;

        if (duration == -1)
        {
            duration = animDuration;
        }

        curIndex++;
        if (curIndex >= dataList.Count)
        {
            curIndex = 0;
        }

        int middleIndex = templates.Length / 2;
        for (int i = 0; i < itemList.Count; i++)
        {
            if (i >= 1)
            {
                itemList[i].transform.DOMove(templates[i - 1].position, duration);
                itemList[i].transform.DORotate(templates[i - 1].eulerAngles, duration);
            }

            if (i == middleIndex)
            {
                SetActiveItem(itemList[i], false, true, duration);
            }
            else if (i == middleIndex + 1)
            {
                SetActiveItem(itemList[i], true, true, duration);
            }
        }

        isTurning = true;
        DelayAction(AnimOver, duration);
    }
    
    public void LastIndex(float duration = -1)
    {
        if (isTurning) return;

        if (duration == -1)
        {
            duration = animDuration;
        }

        curIndex--;
        if (curIndex < 0)
        {
            curIndex = dataList.Count - 1;
        }
        int middleIndex = templates.Length / 2;
        for (int i = 0; i < itemList.Count; i++)
        {
            if (i < itemList.Count - 1)
            {
                itemList[i].transform.DOMove(templates[i + 1].position, duration);
                itemList[i].transform.DORotate(templates[i + 1].eulerAngles, duration);
            }

            if (i == middleIndex)
            {
                SetActiveItem(itemList[i], false, true, duration);
            }
            else if (i == middleIndex - 1)
            {
                SetActiveItem(itemList[i], true, true, duration);
            }
        }

        isTurning = true;
        DelayAction(AnimOver, duration);
    }

    public void AnimOver()
    {
        for (int i = 0; i < itemList.Count; i++)
        {
            Vector3 targetPos = Vector3.zero;
            Vector3 targetRot = Vector3.zero;
            targetPos = templates[i].position;
            targetRot = templates[i].eulerAngles;

            itemList[i].GetComponent<RectTransform>().position = targetPos;
            itemList[i].GetComponent<RectTransform>().eulerAngles = targetRot;
        }

        for (int i = 0; i < itemList.Count; i++)
        {
            int realIndex = GetRealIndex(curIndex - onePageItemCount / 2 + i - 1);
            itemList[i].GetComponentInChildren<Text>().text = GetData(realIndex);
        }

        int middleIndex = templates.Length / 2;

        SetActiveItem(itemList[middleIndex - 1], false, false);
        SetActiveItem(itemList[middleIndex], true, false);
        SetActiveItem(itemList[middleIndex + 1], false, false);

        isTurning = false;
    }

    public void SetActiveItem(GameObject item, bool isActive, bool isAnim, float duration = -1)
    {
        if (isAnim)
        {
            if (isActive)
            {
                item.transform.DOScale(Vector3.one * 1.5f, duration);
                item.GetComponent<Graphic>().DOColor(Color.yellow, duration);
            }
            else
            {
                item.transform.DOScale(Vector3.one, duration);
                item.GetComponent<Graphic>().DOColor(Color.red, duration);
            }
        }
        else
        {
            if (isActive)
            {
                item.transform.localScale = Vector3.one * 1.5f;
                item.GetComponent<Graphic>().color = Color.yellow;
            }
            else
            {
                item.transform.localScale = Vector3.one;
                item.GetComponent<Graphic>().color = Color.red;
            }
        }
    }

    public int GetRealIndex(int index)
    {
        if (index < 0)
        {
            return dataList.Count + index;
        }
        else if (index >= dataList.Count)
        {
            return index - dataList.Count;
        }
        else
        {
            return index;
        }
    }

    public string GetData(int index)
    {
        return dataList[GetRealIndex(index)];
    }

    public IEnumerator QuickChange(int offset)
    {
        int step = Mathf.Abs(offset);

        float curDuration = animDuration * 0.8f;
        for (int i = 0; i < step; i++)
        {
            if (offset > 0)
            {
                NextIndex(curDuration);
            }
            else
            {
                LastIndex(curDuration);
            }
            yield return new WaitForSeconds(curDuration);
        }
    }

    public void OnBeginDrag(PointerEventData eventData)
    {
        if (isTurning) return;
        
        dragStartPos = eventData.position;
        isDragging = true;
    }
   public void OnDrag(PointerEventData eventData)
    {
        if (!isDragging || isTurning) return;

        // 计算拖拽偏移量
        Vector2 dragOffset = eventData.position - dragStartPos;
        
        // 根据滚动方向选择偏移量
        float offset = isVerticalScroll ? dragOffset.y : dragOffset.x;
        
        // 限制拖拽范围
        offset = Mathf.Clamp(offset, -spacing * 2, spacing * 2);

        // 应用偏移到所有item，实现跟随效果
        for (int i = 0; i < itemList.Count; i++)
        {
            // 基于模板位置进行偏移
            Vector3 originalPos = templates[i].position;
            
            // 根据滚动方向应用偏移
            Vector3 offsetPos = originalPos;
            if (isVerticalScroll)
            {
                offsetPos = originalPos + new Vector3(0, offset * 0.5f, 0); // 垂直方向偏移
            }
            else
            {
                offsetPos = originalPos + new Vector3(offset * 0.5f, 0, 0); // 水平方向偏移
            }
    
            itemList[i].transform.position = offsetPos;
        }
    }

    public void OnEndDrag(PointerEventData eventData)
    {
        if (!isDragging) return;
    
        isDragging = false;
    
        // 计算拖拽距离
        Vector2 dragVector = eventData.position - dragStartPos;
        float dragDistance = isVerticalScroll ? dragVector.y : dragVector.x;
    
        // 判断是否超过阈值
        if (Mathf.Abs(dragDistance) >= dragThreshold)
        {
            // 根据拖拽方向决定切换方向
            if (dragDistance > 0)
            {
                if (isVerticalScroll)
                {
                    NextIndex(); // 垂直向上拖拽，切换到上一个
                }
                else
                {
                    LastIndex(); // 水平向右拖拽，切换到上一个
                }
            }
            else
            {
                if (isVerticalScroll)
                {
                    LastIndex(); // 垂直向下拖拽，切换到下一个
                }
                else
                {
                    NextIndex(); // 水平向左拖拽，切换到下一个
                }
            }
        }
        else
        {
            // 如果没有超过阈值，恢复到原始位置
            RecoverToOriginalPosition();
        }
    }

// 恢复到原始位置的动画
    private void RecoverToOriginalPosition()
    {
        if (isTurning) return;
    
        isTurning = true;
    
        // 使用动画恢复到原始位置
        for (int i = 0; i < itemList.Count; i++)
        {
            itemList[i].transform.DOMove(templates[i].position, animDuration * 0.5f).SetEase(Ease.OutQuad);
        }
    
        // 动画完成后重置状态
        DelayAction(() => { isTurning = false; }, animDuration * 0.5f);
    }

}
